﻿
using Renci.SshNet;
using Renci.SshNet.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Windows.Media;
using ExceptionEventArgs = Renci.SshNet.Common.ExceptionEventArgs;

namespace ETC.DLEDLightingSystemPlus.Helpers
{
    public class BanditSFtp
    {
        public event EventHandler<ExceptionEventArgs> OnErrorOccurred;

        private SftpClient _SftpClient;

        //用户名
        private string _UserName;
        //密码
        private string _Password;

        /// <summary>
        /// SFtp地址
        /// </summary>
        public string Address
        {
            get;
            private set;
        }

        /// <summary>
        /// SFTP连接状态
        /// </summary>
        public bool IsConnected
        {
            get
            {
                return _SftpClient != null && _SftpClient.IsConnected;
            }
        }

        public BanditSFtp(string address, string username, string password)
        {
            this.Address = address;
            this._UserName = username;
            this._Password = password;

            _SftpClient = new SftpClient(address, username, password);
            _SftpClient.ConnectionInfo.Timeout = TimeSpan.FromSeconds(3);
            _SftpClient.ErrorOccurred += (sender, e) =>
            {
                if (OnErrorOccurred != null)
                {
                    OnErrorOccurred(this, e);
                }
            };
        }

        /// <summary>
        /// 连接SFTP
        /// </summary>
        /// <returns></returns>
        public bool Connect()
        {
            bool result = false;
            try
            {
                if (!this.IsConnected)
                {
                    _SftpClient.Connect();
                }
                result = true;
            }
            catch (SshConnectionException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return result;
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
            try
            {
                if (_SftpClient != null && this.IsConnected)
                {
                    _SftpClient.Disconnect();
                }
            }
            catch (ObjectDisposedException ex)
            {
                throw new Exception(string.Format("断开SFTP失败，原因：{0}", ex.Message));
            }
        }

        public bool CreateDirectory(string remotePath)
        {
            string parentDir = System.IO.Path.GetDirectoryName(remotePath).Replace("\\", "/");

            if (!_SftpClient.Exists(parentDir))
            {
                this.CreateDirectory(parentDir);
            }

            _SftpClient.CreateDirectory(remotePath);

            return true;
        }

        public bool CreateFile(string remotePath)
        {
            string parentDir = System.IO.Path.GetDirectoryName(remotePath).Replace("\\", "/");

            if (!_SftpClient.Exists(parentDir))
            {
                this.CreateDirectory(parentDir);
            }

            _SftpClient.Create(remotePath);

            return true;
        }

        public bool UploadDirectory(string localDir, string remoteDir)
        {
            localDir = localDir.TrimEnd(new char[] { '\\' });
            remoteDir = remoteDir.TrimEnd(new char[] { '/' });

            string dirName = Path.GetFileName(localDir);

            DirectoryInfo dirInfo = new DirectoryInfo(localDir);

            foreach (var fi in dirInfo.GetFiles())
            {
                string remotePath = string.Format("{0}/{1}", remoteDir, fi.Name);

                UploadFile(fi.FullName, remotePath);
            }

            foreach (var di in dirInfo.GetDirectories())
            {
                string remotePath = string.Format("{0}/{1}", remoteDir, di.Name);

                UploadDirectory(di.FullName, remotePath);
            }

            return true;
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="localPath"></param>
        /// <param name="remotePath"></param>
        /// <returns></returns>
        public bool UploadFile(string localPath, string remotePath)
        {
            using (var fs = File.OpenRead(localPath))
            {
                string parentDir = System.IO.Path.GetDirectoryName(remotePath).Replace("\\", "/");

                if (!_SftpClient.Exists(parentDir))
                {
                    this.CreateDirectory(parentDir);
                }

                _SftpClient.UploadFile(fs, remotePath, (l) =>
                {
                    //Console.WriteLine("Upload : {0}", l);
                });
            }

            return true;
        }

        public bool DownloadFile(string remotePath, string localPath)
        {
            if (_SftpClient.Exists(remotePath))
            {
                string dir = Path.GetDirectoryName(localPath);

                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                using (FileStream fs = File.Create(localPath))
                {
                    _SftpClient.DownloadFile(remotePath, fs, (l) =>
                    {
                        //Console.WriteLine("Download : {0}", l);
                    });
                    fs.Close();
                }

                return true;
            }

            return false;
        }

        public bool DownloadDirectory(string remotePath, string localPath)
        {
            if (!localPath.EndsWith("\\"))
            {
                localPath += "\\";
            }

            var list = _SftpClient.ListDirectory(remotePath);

            foreach (var item in list)
            {
                if (item.Name.Equals(".") || item.Name.Equals(".."))
                {
                    continue;
                }

                string path = localPath + item.Name;
                if (item.IsDirectory)
                {
                    DownloadDirectory(item.FullName, path);
                }
                else
                {
                    DownloadFile(item.FullName, path);
                }
            }

            return true;
        }

        /// <summary>
        /// 读取指定路径的文本
        /// </summary>
        /// <param name="remotePath"></param>
        /// <returns></returns>
        public string ReadText(string remotePath)
        {
            string text = null;

            if (_SftpClient.Exists(remotePath))
            {
                text = _SftpClient.ReadAllText(remotePath);
            }

            return text;
        }

        /// <summary>
        /// 检查目录或文件是否存在
        /// </summary>
        /// <param name="remotePath"></param>
        /// <returns></returns>
        public bool IsExists(string remotePath)
        {
            return _SftpClient.Exists(remotePath);
        }

        /// <summary>
        /// 删除文件或目录
        /// </summary>
        /// <param name="remotePath"></param>
        /// <returns></returns>
        public bool Delete(string remotePath)
        {
            _SftpClient.Delete(remotePath);

            return true;
        }

        /// <summary>
        /// 删除目录,含子目录和文件
        /// </summary>
        /// <param name="remotePath"></param>
        /// <returns></returns>
        public bool DeleteDirectory(string remotePath)
        {
            if (!_SftpClient.Exists(remotePath))
            {
                return true;
            }

            var list = _SftpClient.ListDirectory(remotePath);

            foreach (var item in list)
            {
                if (item.IsDirectory)
                {
                    if (item.Name.Equals(".") || item.Name.Equals(".."))
                    {
                        continue;
                    }
                    DeleteDirectory(item.FullName);
                }
                else
                {
                    item.Delete();
                }
            }

            _SftpClient.DeleteDirectory(remotePath);

            return true;
        }

        /// <summary>
        /// 判断指定的路径是否为空文件夹
        /// </summary>
        /// <param name="remotePath"></param>
        /// <returns></returns>
        public bool IsEmptyDirectory(string remotePath)
        {
            var list = _SftpClient.ListDirectory(remotePath);

            int count = list.Count(s => !s.Name.Equals(".") && !s.Name.Equals(".."));

            return count == 0;
        }

        public void GetFilesAndDirectorys(string remotePath)
        {
            var list = _SftpClient.ListDirectory(remotePath, (l) =>
            {
                Console.WriteLine(l);
            });

            foreach (var item in list)
            {
                Console.WriteLine("{0} : {1}", item.IsDirectory ? "Dir" : "File", item.FullName);
            }
        }

        public List<string> GetFiles(string remotePath)
        {
            List<string> fullNames = new List<string>();
            var list = _SftpClient.ListDirectory(remotePath);

            foreach (var item in list)
            {
                fullNames.Add(item.FullName);
            }

            return fullNames;
        }
    }
}
